<chapter xml:id="ip_addr.h">
<title><tt>__vic/ip_addr.h</tt></title>


<chapter xml:id="ipv4_addr">
<title><tt>ipv4_addr</tt></title>

<code-block lang="C++"><![CDATA[
class ipv4_addr : public ::in_addr
{
public:
    ipv4_addr() = default;
    constexpr ipv4_addr(::in_addr a);
    constexpr explicit ipv4_addr(::in_addr_t a);
    constexpr ipv4_addr(uint8_t a, uint8_t b, uint8_t c, uint8_t d);

    static constexpr ipv4_addr any();
    static constexpr ipv4_addr loopback();

    constexpr bool is_any() const;
    constexpr bool is_loopback() const;

    static bool parse(const char *begin, const char *end, ::in_addr &res);
#if __cpp_lib_string_view // C++17
    static bool parse(std::string_view s, ::in_addr &res);
#else // until C++17
    static bool parse(const std::string &s, ::in_addr &res)
    static bool parse(const char *s, ::in_addr &res);
#endif
};

constexpr ipv4_addr operator&(ipv4_addr a1, ipv4_addr a2);

constexpr bool operator==(ipv4_addr a1, ipv4_addr a2);
constexpr bool operator!=(ipv4_addr a1, ipv4_addr a2);
constexpr bool operator< (ipv4_addr a1, ipv4_addr a2);
constexpr bool operator> (ipv4_addr a1, ipv4_addr a2);
constexpr bool operator<=(ipv4_addr a1, ipv4_addr a2);
constexpr bool operator>=(ipv4_addr a1, ipv4_addr a2);

constexpr bool operator==(ipv4_addr a1, ::in_addr a2);
constexpr bool operator!=(ipv4_addr a1, ::in_addr a2);
constexpr bool operator< (ipv4_addr a1, ::in_addr a2);
constexpr bool operator> (ipv4_addr a1, ::in_addr a2);
constexpr bool operator<=(ipv4_addr a1, ::in_addr a2);
constexpr bool operator>=(ipv4_addr a1, ::in_addr a2);

constexpr bool operator==(::in_addr a1, ipv4_addr a2);
constexpr bool operator!=(::in_addr a1, ipv4_addr a2);
constexpr bool operator< (::in_addr a1, ipv4_addr a2);
constexpr bool operator> (::in_addr a1, ipv4_addr a2);
constexpr bool operator<=(::in_addr a1, ipv4_addr a2);
constexpr bool operator>=(::in_addr a1, ipv4_addr a2);

void to_text_append(::in_addr ip, std::string &res);

template<> struct std::hash<ipv4_addr>;
]]></code-block>

<p>IPv4 адрес. Удобная C++-обёртка для <tt>::in_addr</tt>.</p>

<section><title>Члены класса</title>

<synopsis>
<prototype>ipv4_addr() = default</prototype>
<p>Создаёт неинициализированный IPv4 адрес.</p>
</synopsis>

<synopsis>
<prototype>constexpr ipv4_addr(uint8_t a, uint8_t b, uint8_t c, uint8_t d)</prototype>
<p>Создаёт IPv4 адрес <tt>a.b.c.d</tt>.</p>
</synopsis>

<synopsis>
<prototype>constexpr ipv4_addr(::in_addr a)</prototype>
<prototype>constexpr explicit ipv4_addr(::in_addr_t a)</prototype>
<p>Конвертеры из системных типов.</p>
</synopsis>

<synopsis>
<prototype>static constexpr ipv4_addr any()</prototype>
<p>Возвращает IPv4 адрес <tt>0.0.0.0</tt>.</p>
</synopsis>

<synopsis>
<prototype>static constexpr ipv4_addr loopback()</prototype>
<p>Возвращает IPv4 адрес <tt>127.0.0.1</tt>.</p>
</synopsis>

<synopsis>
<prototype>constexpr bool is_any() const</prototype>
<p>Возвращает <tt>true</tt>, если адрес - <tt>0.0.0.0</tt>.</p>
</synopsis>

<synopsis>
<prototype>constexpr bool is_loopback() const</prototype>
<p>Возвращает <tt>true</tt>, если адрес - <tt>127.0.0.1</tt>.</p>
</synopsis>

<synopsis>
<prototype>static bool parse(const char *begin, const char *end, ::in_addr &amp;res)
</prototype>
<p>Конвертация IPv4 адреса из текстового представления. В случае успеха
возвращается <tt>true</tt>, и <tt>res</tt> содержит сконвертированное
значение.</p>
<note>Ожидаемый входной формат - строго 4 компоненты в десятичном представлении,
разделённые точками.</note>
</synopsis>

<synopsis>
<prototype>static bool parse(std::string_view s, ::in_addr &amp;res) <badge>C++17</badge></prototype>
<p>Альтернативный прототип одноимённой функции для C++17.</p>
</synopsis>

<synopsis>
<prototype>static bool parse(const std::string &amp;s, ::in_addr &amp;res) <badge>until C++17</badge></prototype>
<prototype>static bool parse(const char *s, ::in_addr &amp;res) <badge>until C++17</badge></prototype>
<p>Альтернативные прототипы одноимённой функции до C++17.</p>
</synopsis>

</section>

<section><title>Свободные функции</title>

<synopsis>
<prototype>constexpr ipv4_addr operator&amp;(ipv4_addr a1, ipv4_addr a2)</prototype>
<p>Применяет маску к адресу.</p>
</synopsis>

<synopsis>
<prototype>constexpr bool operator==(ipv4_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator!=(ipv4_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator==(ipv4_addr a1, ::in_addr a2)</prototype>
<prototype>constexpr bool operator!=(ipv4_addr a1, ::in_addr a2)</prototype>
<prototype>constexpr bool operator==(::in_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator!=(::in_addr a1, ipv4_addr a2)</prototype>
<p>Операции проверки на равенство.</p>
</synopsis>

<synopsis>
<prototype>constexpr bool operator&lt; (ipv4_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator> (ipv4_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator&lt;=(ipv4_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator>=(ipv4_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator&lt; (ipv4_addr a1, ::in_addr a2)</prototype>
<prototype>constexpr bool operator> (ipv4_addr a1, ::in_addr a2)</prototype>
<prototype>constexpr bool operator&lt;=(ipv4_addr a1, ::in_addr a2)</prototype>
<prototype>constexpr bool operator>=(ipv4_addr a1, ::in_addr a2)</prototype>
<prototype>constexpr bool operator&lt; (::in_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator> (::in_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator&lt;=(::in_addr a1, ipv4_addr a2)</prototype>
<prototype>constexpr bool operator>=(::in_addr a1, ipv4_addr a2)</prototype>
<p>Операции сравнения. Конкретный порядок может отличаться на разных платформах,
но в пределах одной платформы является математически согласованным.</p>
</synopsis>

<synopsis>
<prototype>void to_text_append(::in_addr ip, std::string &amp;res)</prototype>
<p>Преобразуют IPv4 адрес в десятичное точечное текстовое представление.</p>
</synopsis>

<synopsis>
<prototype>template&lt;> struct std::hash&lt;ipv4_addr></prototype>
<p>Специализация <tt>std::hash</tt>.</p>
</synopsis>

</section>

<section><title>Пример</title>
<code-block lang="C++"><![CDATA[
http_connect(__vic::ipv4_addr{127,0,0,1}, 80);

std::string_view s = ..;
__vic::ipv4_addr ip;
if(__vic::ipv4_addr::parse(s, ip))
    log.info() << "Connecting to " << ip << "...";
else
    log.error("Bad IPv4 address format");
]]></code-block>
</section>

</chapter>


<chapter xml:id="ipv6_addr">
<title><tt>ipv6_addr</tt></title>

<code-block lang="C++"><![CDATA[
class ipv6_addr : public ::in6_addr
{
public:
    ipv6_addr() = default;
    constexpr ipv6_addr(::in6_addr a);
    constexpr ipv6_addr(uint8_t a, uint8_t b, uint8_t c, uint8_t d,
                        uint8_t e, uint8_t f, uint8_t g, uint8_t h,
                        uint8_t i, uint8_t j, uint8_t k, uint8_t l,
                        uint8_t m, uint8_t n, uint8_t o, uint8_t p);
    constexpr ipv6_addr(uint16_t a, uint16_t b, uint16_t c, uint16_t d,
                        uint16_t e, uint16_t f, uint16_t g, uint16_t h)
    explicit ipv6_addr(const ::in_addr &ip4);

    static constexpr ipv6_addr any();
    static constexpr ipv6_addr loopback();

    bool is_any() const;
    bool is_loopback() const;
    bool is_ipv4_mapped() const;
    ipv4_addr to_ipv4() const;

    static bool parse(const char *begin, const char *end, ::in6_addr &res);
#if __cpp_lib_string_view
    static bool parse(std::string_view s, ::in6_addr &res);
#else
    static bool parse(const std::string &s, ::in6_addr &res);
    static bool parse(const char *s, ::in6_addr &res);
#endif
};

ipv6_addr operator&(const ipv6_addr &a1, const ipv6_addr &a2);

constexpr bool operator==(ipv6_addr a1, ipv6_addr a2);
constexpr bool operator!=(ipv6_addr a1, ipv6_addr a2);
constexpr bool operator< (ipv6_addr a1, ipv6_addr a2);
constexpr bool operator> (ipv6_addr a1, ipv6_addr a2);
constexpr bool operator<=(ipv6_addr a1, ipv6_addr a2);
constexpr bool operator>=(ipv6_addr a1, ipv6_addr a2);

constexpr bool operator==(ipv6_addr a1, ::in6_addr a2);
constexpr bool operator!=(ipv6_addr a1, ::in6_addr a2);
constexpr bool operator< (ipv6_addr a1, ::in6_addr a2);
constexpr bool operator> (ipv6_addr a1, ::in6_addr a2);
constexpr bool operator<=(ipv6_addr a1, ::in6_addr a2);
constexpr bool operator>=(ipv6_addr a1, ::in6_addr a2);

constexpr bool operator==(::in6_addr a1, ipv6_addr a2);
constexpr bool operator!=(::in6_addr a1, ipv6_addr a2);
constexpr bool operator< (::in6_addr a1, ipv6_addr a2);
constexpr bool operator> (::in6_addr a1, ipv6_addr a2);
constexpr bool operator<=(::in6_addr a1, ipv6_addr a2);
constexpr bool operator>=(::in6_addr a1, ipv6_addr a2);

void to_text_append(::in6_addr ip, std::string &res);
string_buffer &operator<<(string_buffer &s, ::in6_addr ip);

template<> struct std::hash<ipv6_addr>;
]]></code-block>

<p>Аналог <xref to="ipv4_addr"/> для IPv6/<tt>::in6_addr</tt>.</p>

<section><title>Члены класса, отсутсвующие у <tt>ipv4_addr</tt></title>

<synopsis>
<prototype>explicit ipv6_addr(const ::in_addr &amp;ip4)</prototype>
<p>Создаёт IPv4-mapped IPv6 address.</p>
<postcondition><tt>is_ipv4_mapped() == true</tt></postcondition>
</synopsis>

<synopsis>
<prototype>static constexpr ipv6_addr any()</prototype>
<p>Возвращает IPv6 адрес <tt>::</tt>.</p>
</synopsis>

<synopsis>
<prototype>static constexpr ipv6_addr loopback()</prototype>
<p>Возвращает IPv6 адрес <tt>::1</tt>.</p>
</synopsis>

<synopsis>
<prototype>bool is_any() const</prototype>
<p>Возвращает <tt>true</tt>, если адрес - <tt>::</tt>.</p>
</synopsis>

<synopsis>
<prototype>bool is_loopback() const</prototype>
<p>Возвращает <tt>true</tt>, если адрес - <tt>::1</tt>.</p>
</synopsis>

<synopsis>
<prototype>bool is_ipv4_mapped() const</prototype>
<p>Возвращает <tt>true</tt>, если значение является IPv4-mapped IPv6 address.</p>
</synopsis>

<synopsis>
<prototype>ipv4_addr to_ipv4() const</prototype>
<p>Конвертирует IPv4-mapped IPv6 address в <tt>ipv4_addr</tt>.</p>
<precondition><tt>is_ipv4_mapped() == true</tt></precondition>
</synopsis>

</section>

</chapter>


</chapter>
